package cn.tedu.charging.order.service.impl;

import cn.tedu.charging.common.pojo.GunStatusUpdateParam;
import cn.tedu.charging.common.pojo.JsonResult;
import cn.tedu.charging.common.utils.JsonUtils;
import cn.tedu.charging.common.vo.UserInfoVO;
import cn.tedu.charging.order.constant.Constants;
import cn.tedu.charging.order.constant.MqttConstant;
import cn.tedu.charging.order.feign.DeviceClient;
import cn.tedu.charging.order.feign.UserClient;
import cn.tedu.charging.order.mqtt.MqttProducer;
import cn.tedu.charging.order.pojo.dto.ChargingDto;
import cn.tedu.charging.order.pojo.dto.StationInfoDto;
import cn.tedu.charging.order.pojo.dto.UserInfoDto;
import cn.tedu.charging.order.pojo.param.OrderAddParam;
import cn.tedu.charging.order.pojo.po.OrderMQPO;
import cn.tedu.charging.order.rabbit.RabbitMQOrderProducer;
import cn.tedu.charging.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 创建订单
 * 1. 生成订单号
 * 2. 获取场站信息和设备信息
 * 3. 获取用户车辆信息
 * 4. 给设备发送开始充电指令
 * 5. 修改充电桩的状态 为 使用中
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Override
    public String createOrder(OrderAddParam orderAddParam) {
        //创建订单的流程 自项向下编程
        //1.生成订单号
        String orderNo =getOrderNo();

        //2.获取场站信息和设备信息
        StationInfoDto stationInfoDto = getUserInfoByGunId(orderAddParam.getGunId());

        //3.获取用户车辆信息
        UserInfoDto userInfoDto =getUserInfoByUserId(orderAddParam.getUserId());

        //4.给设备发送开始冲电指令
        starCharging(orderNo,orderAddParam.getPileId(),orderAddParam.getGunId());

        //5.修改充电桩的状态为 使用中
        Boolean success = updateGunStatusBusy(orderAddParam.getGunId());
        
        //6.
        sendOrderMessage(orderNo);
        return orderNo;
    }
@Autowired
  private RabbitMQOrderProducer rabbitMQOrderProducer;
    private void sendOrderMessage(String orderNo) {
        OrderMQPO orderMQPO=new OrderMQPO();
        orderMQPO.setOrderNo(orderNo);
        rabbitMQOrderProducer.sendOrder(orderMQPO);
    }

    @Autowired
    private MqttProducer mqttProducer;
    /**
     * 给设备发送开始充电指令
     */
    private void starCharging(String orderNo, Integer pileId, Integer gunId) {
    String topic = MqttConstant.TOPIC_START_CHARGING_PREFIX+"/"+pileId;
        ChargingDto chargingDto=new ChargingDto();
        chargingDto.setOrderNo(orderNo);
        chargingDto.setPileId(pileId);
        chargingDto.setGunId(gunId);
        chargingDto.setMsg(Constants.START_CHARGING);
        String json = JsonUtils.toJson(chargingDto);
        log.debug("订单服务发送开始充电指令到设备topic:{},消息:{}",topic,json);
        Boolean send =mqttProducer.send(topic,json);
        log.debug("订单服务发送开始充电指令到设备topic:{},消息:{},结果:{}",topic,json,send);
        //如果发送失败,需要重试,需要告警
    }
    @Autowired
    private DeviceClient deviceClient;
    /**
     * 修改充电桩的状态 为 使用中
     */
    private Boolean updateGunStatusBusy(Integer gunId) {
        GunStatusUpdateParam param=new GunStatusUpdateParam();
        param.setGunId(gunId);
        param.setStatus(Constants.GUN_STATS_BUSY);
        JsonResult<Boolean> jsonResult=deviceClient.updateGunStatus(param);
        if(jsonResult != null){
            return jsonResult.getData();
        }
        return false;
    }
    /**
     * private 最小
     * 默认
     * 保护
     * public
     */
    @Autowired
    private UserClient userClient;

    /**
     * 获取用户车辆信息
     */
    private UserInfoDto getUserInfoByUserId(Integer userId) {
        JsonResult<UserInfoVO> userCarInfo =userClient.getUserCarInfo(userId);
        if (userCarInfo != null) {
            UserInfoVO data=userCarInfo.getData();
            if(data!=null){
                UserInfoDto userInfoDto=new UserInfoDto();
                userInfoDto.setCarId(data.getCarId());
                return userInfoDto;
            }
        }
        return null;
    }

    /**
     * 通过枪id 获取场站信息
     */
    private StationInfoDto getUserInfoByGunId(Integer gunId) {
        JsonResult<UserInfoVO> userCarInfo = userClient.getUserCarInfo(gunId);
        if (userCarInfo != null) {
            UserInfoVO data = userCarInfo.getData();
            if (data != null) {
                StationInfoDto stationInfoDto = new StationInfoDto();
                //stationInfoDto.setStationId(data.getStationId());
                //todo copyProperties 底层实现
                BeanUtils.copyProperties(data,stationInfoDto);
                return stationInfoDto;
            }
        }
        return null;
    }

    /**
     * 生成订单号
     */
    private String getOrderNo() {
        return "999";
    }

}
